-------------------------------------------------------------------------------
-- Archivo:                         alu.vhdl
-- Fecha de creacion:               04/02/2011
-- Ultima fecha de modificacion:    05/02/2011
-- Diseñador:                       Liliana Andrade
-- Diseño:                          alu
-- Proposito:                       Unidad aritmetica-logica d 4 bits encauzada
--                                  en cinco etapas, realiza suma, resta, mult.
--                                  y operaciones logicas
-------------------------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.all;

entity alu is
	port(
        A_i         : in  std_logic_vector(3 downto 0); -- operandos A
        B_i         : in  std_logic_vector(3 downto 0); -- operandos B
        C_i         : in  std_logic;                    -- acarreo de entrada
        ALU_OP_i    : in  std_logic_vector(3 downto 0); -- codigo de operacion
        ALU_o       : out std_logic_vector(3 downto 0); -- result seleccionado
        C_o         : out std_logic;
        N_o         : out std_logic;
        OVF_o       : out std_logic;
        Z_o         : out std_logic;
        CLK         : in  std_logic
	);
end alu;

architecture structural of alu is

    component sum_encauzado
        port (
		    A_i         : in  std_logic_vector (3 downto 0);
		    B_i         : in  std_logic_vector (3 downto 0);
		    CONTROL_i   : in  std_logic;
		    S_o         : out  std_logic_vector (3 downto 0);
		    C_o         : out  std_logic;
		    C_PREV_o    : out std_logic;
		    CLK         : in std_logic
         );
    end component;
 

    component multiplicador_encauzado
        port(
 	        X_i : in  std_logic_vector(3 downto 0);
            Y_i : in  std_logic_vector(3 downto 0);
            Z_o : out  std_logic_vector(3 downto 0);
	        CLK : in  std_logic
        );
    end component;


	component lu
		port(
            A_i         : in  std_logic_vector(3 downto 0);
            B_i         : in  std_logic_vector(3 downto 0);
            ALU_OP_i    : in  std_logic_vector(3 downto 0);
            LU_o        : out std_logic_vector(3 downto 0);
            CLK         : in std_logic
		);
	end component;


	component mux2to1
		port(
			I0_i     	: in std_logic_vector(3 downto 0);
			I1_i     	: in std_logic_vector(3 downto 0);
			SEL_i    	: in std_logic;
			OUTPUT_o 	: out std_logic_vector(3 downto 0)
		);
	end component;


	component mux4to1
		port(
			I0_i     	: in std_logic_vector(3 downto 0);
			I1_i     	: in std_logic_vector(3 downto 0);
			I2_i     	: in std_logic_vector(3 downto 0);
			I3_i     	: in std_logic_vector(3 downto 0);
			SEL_i    	: in std_logic_vector(1 downto 0);
			OUTPUT_o 	: out std_logic_vector(3 downto 0)
		);
	end component;


    component banderas
        port ( 
	        I_i         : in std_logic_vector(3 downto 0);
	        C_PREV_i    : in std_logic;
	        C_i         : in std_logic;
	        CARRY_o     : out  std_logic;
	        N_o         : out  std_logic;
	        OVF_o       : out  std_logic;
	        Z_o         : out  std_logic
	    );
    end component;


	-- cables que comunican hacia mux2to1
	signal sum_wire     : std_logic_vector(3 downto 0);
	signal mult_wire    : std_logic_vector(3 downto 0);

	-- cables que comunican hacia mux4to1
	signal mux0_wire    : std_logic_vector(3 downto 0);
	signal lu_wire      : std_logic_vector(3 downto 0);
	signal mem_wire     : std_logic_vector(3 downto 0);

	-- cables que comunican hacia la logica de banderas
	signal carry_wire   : std_logic;
	signal cprev_wire   : std_logic;
	signal ban_wire     : std_logic_vector(3 downto 0);

  
	begin

		SUMADOR : sum_encauzado port map (
            A_i         => A_i,
		    B_i         => B_i,
		    CONTROL_i   => C_i,
		    S_o         => sum_wire,
		    C_o         => carry_wire,
		    C_PREV_o    => cprev_wire,
            CLK         => CLK
		);


		MULTIPLICADOR : multiplicador_encauzado port map (
            X_i         => A_i,
            Y_i         => B_i,
	        Z_o         => mult_wire,
            CLK         => CLK
		);


		LOGIC_UNIT : lu port map (
            A_i         => A_i,
            B_i         => B_i,
            ALU_OP_i    => ALU_OP_i,
            LU_o        => lu_wire,
            CLK         => CLK
		);


		mem_wire        <= (others => '0');


		MUX : mux2to1 port map (
            I0_i     	=> sum_wire,
			I1_i     	=> mult_wire,
			SEL_i    	=> ALU_OP_i(1),
			OUTPUT_o 	=> mux0_wire
		);


		MUX_ALU : mux4to1 port map (
			I0_i        => mux0_wire,
--			I1_i        => mux0_wire,
--			I2_i        => lu_wire,
			I1_i        => lu_wire,
			I2_i        => mux0_wire,
			I3_i        => mem_wire,
			SEL_i       => ALU_OP_i(3 downto 2),
			OUTPUT_o    => ban_wire
		);


		FLAGS : banderas port map (
	        I_i         => ban_wire,
	        C_PREV_i    => cprev_wire,
	        C_i         => carry_wire,
	        CARRY_o     => C_o,
	        N_o         => N_o,
	        OVF_o       => OVF_o,
	        Z_o         => Z_o
		);


        ALU_o   <= ban_wire;
  
end structural;
